package com.CMUBiS.PageServlets;
import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

import com.CMUBiS.Data.Error;
import com.CMUBiS.Data.Footer;
import com.CMUBiS.Data.GlobalVars;
import com.CMUBiS.Data.Header;
import com.CMUBiS.PageControllers.RegisterUserController;
import com.CMUBiS.util.StopWatch;

/**
 * This servlet registers a new user in the database
 * 
 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
 * @version 0.1
 * @since 0.1
 * @date 04/05/2011
 * 
 */
@WebServlet(name="RegisterUserServlet", urlPatterns="/registeruser")
public class RegisterUserServlet extends HttpServlet {
	// As servlets are not thread safe, we only have static variables here
	private static final long serialVersionUID = 6423041006628438743L;
	private static final String EMPTY = "";
	private static final String title = "Register User";
	
	/**
	 * Get the page, calls the page to be made
	 * We used to check the parameters in here, but I moved it to a controller object to keep the logic away from the layout
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		if(GlobalVars.isHTML4){
			makePage(request, response, Boolean.FALSE);
		}else{
			PrintWriter out = response.getWriter();
			response.setContentType("application/json");
			Boolean registerUser = GlobalVars.db.insertUser(request.getParameter("username"), request.getParameter("password"), request.getParameter("email"), request.getParameter("firstName"), request.getParameter("lastName"));
			int userID = GlobalVars.db.checkUsernamePassword(request.getParameter("username"), request.getParameter("password"));
			String authToken ="";
			if(registerUser){
				out.println("{\"registeruser\":\"true\",\"userID\":\""+userID+"\"}");
				
				System.out.println("Created User...!");
			}else{
				out.println("{\"registeruser\":\"false\"}");
				System.out.println("Could not created User...");
			}
		}
	}
	
	
	
	/**
	 * Sets that this is the first time the page has been loaded by the user
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		if(GlobalVars.isHTML4){
			makePage(request, response, Boolean.TRUE);
		}else{
			PrintWriter out = response.getWriter();
			response.setContentType("application/json");
			Boolean registerUser = GlobalVars.db.insertUser(request.getParameter("username"), request.getParameter("password"), request.getParameter("email"), request.getParameter("firstName"), request.getParameter("lastName"));
			int userID = GlobalVars.db.checkUsernamePassword(request.getParameter("username"), request.getParameter("password"));
			String authToken ="";
			if(registerUser){
				out.println("{\"registeruser\":\"true\",\"userID\":\""+userID+"\"}");
				
				System.out.println("Created User...!");
			}else{
				out.println("{\"registeruser\":\"false\"}");
				System.out.println("Could not created User...");
			}
		}
	}
	
	/**
	 * This method starts the page timer, writes the header, creates the HTML for the page, writes the stats, and the footer
	 * If the user has entered all of the correct information, then we'll insert them in to the database
	 * 
	 * @param request
	 * @param response
	 * @param errorString
	 * @throws ServletException
	 * @throws IOException
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void makePage(HttpServletRequest request, HttpServletResponse response, Boolean isGet)  throws ServletException, IOException {
		if(request !=null && response != null){
			// Do the timer if we are collecting stats
			StopWatch timer;
			if(GlobalVars.collectStats){
				timer = new StopWatch();
				timer.start();
			}
			
			// Create a new page controller for this page, it will get and process the data
			RegisterUserController vars = new RegisterUserController();
			vars.checkInputs(request);
			
			// If all of the user's details are correct, write the user to the database and continue to the login page with the correct info inserted
			if(vars.getErrors().size() == 0){
				if(vars.insertUser()){
					timer.stop();
					response.sendRedirect(vars.getRedirectURL());
				}
			}
			
			// We are using PrintWriter to be friendly to the international community. PrintWrite auto-converts coding
			PrintWriter out = response.getWriter();
	
			// Set the return type
			response.setContentType("text/html");
			
			// Write the page header
			Header.writeHeader(out, title, vars.getUserIDString(), vars.getAuthTokenString());
			
			// If the output is to be suppressed then we'll redirect the output
			if(vars.getSuppressOutput())
				out = new PrintWriter(GlobalVars.blackHole);
			
			// Do HTML4 or 5 depending on the global variables
			if(GlobalVars.isHTML4)
				createHTML4(out, vars, isGet);
			else
				createHTML5(out, vars, isGet);
			
			// Redirect the output to start writing the the user again in case we were putting it in the black hole
			out = response.getWriter();
			
			/*
			 * Output any errors. These don't need to be too pretty since we hope there isn't any!
			 * We put them here to help with debug and info, the page above should show pretty ones for users
			 */
			if(GlobalVars.printAllErrors){
				out.println("<BR />Errors: " + vars.getErrors().size());
				for(Error error: vars.getErrors())
					out.println("<BR />" + error.getErrorNumber() + " " +error.toString());
			}
			
			/*
			 * Process the page time
			 */
			if(GlobalVars.collectStats){
				timer.stop();
				vars.setTotalTime(timer.getTimeTaken());
				GlobalVars.addStats(request, out, vars);
			}
			
			// Write the page footer
			Footer.writeFooter(out);
		}
	}
	
	/**
	 * Creates the HTML4 version of the website
	 * 
	 * @param request The incoming request
	 * @param response The response sent to the user
	 * @param out The out writer to write the HTML to
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void createHTML4(PrintWriter out, RegisterUserController vars, Boolean isGet){
		if(out != null && vars != null)
		try{
			// Get the data needed to display the page
			vars.getHTML4Data();
			vars.processHTML4();
			
			//TODO: pretty print errors depending on the what the user submitted
			
			/*
			 * Make the input form
			 */
			out.println("<form name=\"register_user\" action=\"registeruser\" method=\"POST\">");
			out.println("<div id=\"center\">");	
			
			out.println("<div id=\"floatright\">Username: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"username\" size=\"30\" value=\""+ vars.getUsername() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">Password: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"password1\" size=\"30\" value=\""+ vars.getPassword1() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">Confirm Password: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"password2\" size=\"30\" value=\""+ vars.getPassword2() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">E-mail address: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"email1\" size=\"30\" value=\""+ vars.getEmail1() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">Confirm E-mail address: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"email2\" size=\"30\" value=\""+ vars.getEmail2() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">First name: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"firstname\" size=\"30\" value=\""+ vars.getFirstname() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">Last name: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"lastname\" size=\"30\" value=\""+ vars.getLastname() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">Street: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"street\" size=\"50\" value=\""+ vars.getStreet() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">Town: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"town\" size=\"50\" value=\""+ vars.getTown() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">Zip code: </div>");
			out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"zip\" size=\"10\" maxlength=\"10\" value=\""+ vars.getZip() + "\"/> </div>");
			
			out.println("<div id=\"floatright\">State: </div>");
			out.println("<div id=\"floatcenter\">");
			out.println("<select name=\"state\">");
			
			String[] stateSelections = vars.getStateSelections();
			if(stateSelections != null)
				for(String selection: stateSelections)
					out.println(selection);
			
			out.println("</select>");
			out.println("</div>");
			
			out.println("<div id=\"floatright\"><input type=\"submit\" value=\"Register\"></div>");
			
			out.println("</div>");
			out.println("</form>");
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * Creates the HTML5 version of the website
	 * 
	 * @param request The incoming request
	 * @param response The response sent to the user
	 * @param out The out writer to write the HTML to
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void createHTML5(PrintWriter out, RegisterUserController vars, Boolean isGet){
		if(out != null && vars != null)
		try{
			// Get the data needed to display the page
			vars.getHTML4Data();
			vars.processHTML4();
			
			
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}
}
